/*
 * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
 * SPDX-License-Identifier: Apache-2.0
 */
#include "sdkconfig.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/ringbuf.h"

#include "esp_jtag_vendord.h"
#include "esp_jtag_main.h"
#include "usb_config.h"
#include "usbd_core.h"
static const char *TAG = " eub_vendor "; // 日志标签

/* 定义环形缓冲区大小和USB忙超时时间 */
#define USB_RCVBUF_SIZE  4096   // 接收缓冲区大小
#define USB_SNDBUF_SIZE  4096   // 发送缓冲区大小
#define USB_BUSY_TOUT_US 100000 /* 100ms超时时间 */
typedef struct {
    RingbufHandle_t usb_rcvbuf;
    RingbufHandle_t usb_sndbuf;
    TaskHandle_t usb_tx_task_handle;
    /*用于缓存usb接收到的数据*/
    uint8_t epout_buf[EUB_VENDORD_EPSIZE]; /* Endpoint Transfer buffer */
} eub_vendord_interface_t;

static eub_vendord_interface_t s_eub_vendord_itf;
//开启第一次读usb-jtag数据，在usb配置成功后

void start_first_usbjtag_read(void)
{
    usbd_ep_start_read(0, ESP_JTAG_OUT_EP, s_eub_vendord_itf.epout_buf, EUB_VENDORD_EPSIZE);
}

void esp_jtag_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
    (void)busid;
    BaseType_t res = xRingbufferSendFromISR(s_eub_vendord_itf.usb_rcvbuf,
                                            s_eub_vendord_itf.epout_buf, nbytes, NULL);
    if (res != pdTRUE) {
        ESP_LOGE(TAG, "Cannot write to usb_rcvbuf ringbuffer (free %d of %d)!",
                 xRingbufferGetCurFreeSize(s_eub_vendord_itf.usb_rcvbuf), USB_RCVBUF_SIZE);
        abort();
    }
    //第一次读usb-jtag数据，在usb配置成功后 `eub_vendord_start`
    usbd_ep_start_read(0, ESP_JTAG_OUT_EP, s_eub_vendord_itf.epout_buf, EUB_VENDORD_EPSIZE);
}
//用来接收数据忙标志
//uint8_t vendord_busy_cnt = 0;
// 设备-->主机
volatile int cnt_flag = 0;
void esp_jtag_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
    cnt_flag = 0;
    // (void)busid;
    // uint32_t size;
    // static uint8_t *last_acquired_item = NULL;
    // ESP_EARLY_LOGI(TAG, "esp_jtag_in_callback nbytes=%d", nbytes);
    // if ((nbytes % EUB_VENDORD_EPSIZE) == 0 && nbytes) {
    //     /* send zlp */
    //     usbd_ep_start_write(0, ESP_JTAG_IN_EP, NULL, 0);
    // } else
    // if (last_acquired_item) {
    //     vRingbufferReturnItemFromISR(s_eub_vendord_itf.usb_sndbuf, last_acquired_item,NULL);
    //     last_acquired_item=NULL;
    //     vendord_busy_cnt--;
    // }
    // if (vendord_busy_cnt) //vendord_busy_cnt=0表示Ringbuffer无数据
    // {
    //     //!这里不会size超过usb端点大小，usb_sndbuf不可分割的，里面的每一项不会超过64字节
    //     ESP_EARLY_LOGI(TAG, "vendord_busy_cnt=%d", vendord_busy_cnt);

    //     uint8_t *buf = xRingbufferReceiveFromISR(s_eub_vendord_itf.usb_sndbuf, &size);
    //     if (buf)
    //     {
    //         last_acquired_item = buf;
    //         usbd_ep_start_write(0, ESP_JTAG_IN_EP, buf, size);
    //     }
    // }
    //ESP_EARLY_LOGI(TAG, "esp_jtag_in_callback[%d]total_bytes=%d", in_cnt, nbytes);
}

// 发送数据到USB接口
int eub_vendord_send_item(const void *buf, const size_t size)
{
    // ESP_LOGE(TAG, "eub_vendord_send_item size=%d", size);
    // // 等待USB接口
    // if (vendord_busy_cnt) {
    //     vendord_busy_cnt++;
    //     //!这里不会size超过usb端点大小，usb_sndbuf不可分割的，里面的每一项不会超过64字节
    //     /* 发送数据到环形缓冲区 */
    //     // 发送数据到USB接口,成功发送多少要看esp_jtag_in_callback的nbytes
    //     if (xRingbufferSend(s_eub_vendord_itf.usb_sndbuf, buf, size, pdMS_TO_TICKS(1000)) != pdTRUE) {
    //         ESP_LOGE(TAG, "Cannot write to usb_sndbuf ringbuffer (free %d of %d)!",
    //                  xRingbufferGetCurFreeSize(s_eub_vendord_itf.usb_sndbuf), USB_SNDBUF_SIZE);

    //         return 0;
    //     }
    // }
    // /* 启动usb传输 */
    // usbd_ep_start_write(0, ESP_JTAG_IN_EP, buf, size);
    //ESP_EARLY_LOGI("MIDUO", "eub_vendord_send_item =%d", size);

    if (xRingbufferSend(s_eub_vendord_itf.usb_sndbuf, buf, size, pdMS_TO_TICKS(1000)) != pdTRUE) {
        ESP_LOGE(TAG, "Cannot write to usb_sndbuf ringbuffer (free %d of %d)!",
                 xRingbufferGetCurFreeSize(s_eub_vendord_itf.usb_sndbuf), USB_SNDBUF_SIZE);
        return 0;
    }
    return size;
}

static void usb_send_task(void *pvParameters)
{
    size_t total_bytes;

    ESP_LOGI(TAG, "usb_send_task is ready!");
    for (;;) {
        uint8_t *buf = xRingbufferReceive(s_eub_vendord_itf.usb_sndbuf, &total_bytes, portMAX_DELAY);
        //ESP_EARLY_LOGI("MIDUO", "total_bytes =%d", total_bytes);

        //ESP_LOG_BUFFER_HEXDUMP("res", buf, total_bytes, ESP_LOG_DEBUG);

        // if (!eub_endpt_transfer(s_rhport, s_eub_vendord_itf.ep_in, buf, total_bytes)) {
        //     ESP_LOGE(TAG, "USB transfer error on EP:%x", s_eub_vendord_itf.ep_in);
        //     eub_abort();
        // }
        while (cnt_flag)
            ;
        cnt_flag = 1;
        // ESP_LOGE(TAG, "usbd_ep_start_write[%d]total_bytes=%d", i, total_bytes);
        usbd_ep_start_write(0, ESP_JTAG_IN_EP, buf, total_bytes);
        vRingbufferReturnItem(s_eub_vendord_itf.usb_sndbuf, buf);
    }

    vTaskDelete(NULL);
}

// 从USB接口接收数据
void *eub_vendord_recv_acquire_item(size_t *item_size)
{
    //usb_rcvbuf是不可分割的环形缓冲区
    return xRingbufferReceive(s_eub_vendord_itf.usb_rcvbuf, item_size, portMAX_DELAY);
}

// 释放接收到的数据
void eub_vendord_free_item(void *item)
{
    vRingbufferReturnItem(s_eub_vendord_itf.usb_rcvbuf, item);
}

// 启动USB供应商接口
void eub_vendord_start(void)
{
    ESP_LOGD(TAG, "%s", __func__);

    static bool init = false;

    if (!init) {
        /* We would like to process OpenOCD packages one by one. RINGBUF_TYPE_NOSPLIT allows us to do it. */
        s_eub_vendord_itf.usb_rcvbuf = xRingbufferCreate(USB_RCVBUF_SIZE, RINGBUF_TYPE_NOSPLIT);
        if (!s_eub_vendord_itf.usb_rcvbuf) {
            ESP_LOGE(TAG, "Cannot allocate USB receive buffer!");
            ESP_JTAG_ABORT();
        }

        s_eub_vendord_itf.usb_sndbuf = xRingbufferCreate(USB_SNDBUF_SIZE, RINGBUF_TYPE_NOSPLIT);
        if (!s_eub_vendord_itf.usb_sndbuf) {
            ESP_LOGE(TAG, "Cannot allocate USB send buffer!");
            ESP_JTAG_ABORT();
        }
        if (xTaskCreate(usb_send_task,
                        "usb_send_task",
                        4 * 1024,
                        NULL,
                        EUB_VENDORD_USB_TASK_PRI,
                        &s_eub_vendord_itf.usb_tx_task_handle) != pdPASS) {
            ESP_LOGE(TAG, "Cannot create USB send task!");
            abort();
        }

        init = true;
    }
}
//停止USB供应商接口
void eub_vendord_stop(void)
{
    if (s_eub_vendord_itf.usb_rcvbuf) {
        vRingbufferDelete(s_eub_vendord_itf.usb_rcvbuf);
        s_eub_vendord_itf.usb_rcvbuf = NULL;
    }
    if (s_eub_vendord_itf.usb_sndbuf) {
        vRingbufferDelete(s_eub_vendord_itf.usb_sndbuf);
        s_eub_vendord_itf.usb_sndbuf = NULL;
    }
    if (s_eub_vendord_itf.usb_tx_task_handle) {
        vTaskDelete(s_eub_vendord_itf.usb_tx_task_handle);
        s_eub_vendord_itf.usb_tx_task_handle = NULL;
    }
}